/*& BEGIN SMO/ETU/04/20167/LB : Portage vers SDK 30                         */
#include "SDK30.H"
#include "_emvdctag_.h"
#include "_emvdc_.h"

#include "del_lib.h"		
#ifdef _TRACK_IAC_DC_		
#include "spy.h"			
#endif
/*& END SMO/ETU/04/20167/LB                                                 */

static DEL DELLocale;
static StructProcessStep _DELLocale;
extern int USR_ServiceCall(unsigned short num_appli, unsigned short service,
    unsigned int data_size, void *data, int *ret_code);

/** Track message */
static void TrackIAC(const DEL *EntryDel, DEL *OutputDel);
#ifdef _TRACK_IAC_DC_															
#define I_EMVDC_Type_Appli        96 /* EMVDC appli number             */	
static StructProcessStep _DELSpy;
#endif

#ifndef __DEL_DEFINED__

#ifdef _SECDEL_
int SecDEL_init(DEL *aDEL)
{
    int i;

    aDEL->current = 0;
    aDEL->count = 0;
    for (i = 0; i < MAX_DATA_ELEMENT; i++)
    {
        aDEL->list[i].tag = 0;
        aDEL->list[i].length = 0;
        aDEL->list[i].ptValue = &(aDEL->ValBuf[i][0]);
        memclr(&(aDEL->ValBuf[i][0]), MAX_ELT_LENGTH);
    }

    return (OK);
}

int SecDEL_AddDataElement(DEL *aDEL, const DataElement *AnElement)
{
    if (aDEL->count < MAX_DATA_ELEMENT)
    {
        aDEL->list[aDEL->count].tag = AnElement->tag;
        if (AnElement->length < MAX_ELT_LENGTH)
        {
            aDEL->list[aDEL->count].length = AnElement->length;
        }
        else
        {
            aDEL->list[aDEL->count].length = MAX_ELT_LENGTH;
        }
        if (AnElement->ptValue != NULL)
        {
            //		memcpy(aDEL->list[aDEL->count].ptValue, AnElement->ptValue, AnElement->length);
            memcpy(&(aDEL->ValBuf[aDEL->count][0]), AnElement->ptValue, aDEL
                ->list[aDEL->count].length);
            aDEL->list[aDEL->count].ptValue = &(aDEL->ValBuf[aDEL->count][0]);
        }
        aDEL->count++;
        return 0;
    }
    else
        return  - 1;

}


DataElement *SecDEL_GetDataElement(DEL *aDEL, int index)
{
    if ((aDEL != NULL) && (index > 0) && (index <= aDEL->count))
    {
        return ((&(aDEL->list[index - 1])));
    }
    else
    {
        return NULL;
    }

}

int SecDEL_GetCount(DEL *aDEL)
{
    if (aDEL != NULL)
    {
        return aDEL->count;
    }
    else
        return  - 1;

}

int SecDEL_CopyDEL(DEL *Source, DEL *Destination)
{
    int i;
    if ((Source != NULL) && (Destination != NULL))
    {
        Destination->current = Source->current;
        Destination->count = Source->count;
        for (i = 0; i < MAX_DATA_ELEMENT; i++)
        {
            Destination->list[i].tag = Source->list[i].tag;
            Destination->list[i].length = Source->list[i].length;
            /*&BEGIN  FT/531/MA   Management of SECDEL functions                  */
            //			Destination->list[i].ptValue = &(Destination->ValBuf[i][0]);
            /*&END  FT/531/MA   Management of SECDEL functions                  */
            if (Source->list[i].length != 0)
            {
                memcpy(&(Destination->ValBuf[i][0]), Source->ValBuf[i], Source
                    ->list[i].length);
            }
        }
    }
    return OK;
}

/*&BEGIN smo/etu/04/20518/ma   new spdh */

int SecDEL_ConcatDEL(DEL *Source, DEL *Destination)
{
    int i, j;
    if ((Source != NULL) && (Destination != NULL))
    {
        Destination->current = Source->current;
        for (i = Destination->count, j = 0; i < MAX_DATA_ELEMENT; i++, j++)
        {
            Destination->list[i].tag = Source->list[j].tag;
            Destination->list[i].length = Source->list[j].length;
            /*&BEGIN  FT/531/MA   Management of SECDEL functions                  */
            //			Destination->list[i].ptValue = &(Destination->ValBuf[i][0]);
            /*&END  FT/531/MA   Management of SECDEL functions                  */
            if (Source->list[j].length != 0)
            {
                memcpy(&(Destination->ValBuf[i][0]), Source->ValBuf[j], Source
                    ->list[j].length);
            }
        }

        Destination->count = Source->count + Destination->count;
    }
    return OK;
}

/*&END    smo/etu/04/20518/ma   new spdh */

DataElement *SecDEL_GetFirstDataElement(DEL *aDEL)
{
    if ((aDEL != NULL) && (aDEL->count > 0))
    {
        aDEL->current = 0;
        return (DataElement*)(&(aDEL->list[0]));
    }
    else
    {
        return NULL;
    }
}


DataElement *SecDEL_GetNextDataElement(DEL *aDEL)
{

    if (aDEL == NULL)
        return NULL;

    aDEL->current++;

    if (aDEL->current < aDEL->count)
    {
        return (DataElement*)(&(aDEL->list[aDEL->current]));
    }
    else
    {
        aDEL->current = 0;
        return NULL;
    }
}


void SecDEL_AddToVal(DEL *aDEL, _DEL_ *_vDEL)
{
    int i;

    _DEL_init(_vDEL);
    if (aDEL != NULL)
    {
        _vDEL->current = aDEL->current;
        _vDEL->count = aDEL->count;
        for (i = 0; i < aDEL->count; i++)
        {
            _vDEL->list[i].tag = aDEL->list[i].tag;
            _vDEL->list[i].length = aDEL->list[i].length;
            if (aDEL->list[i].ptValue != NULL)
            {
                memcpy(_vDEL->list[i].ptValue, aDEL->list[i].ptValue, aDEL
                    ->list[i].length);
            }
        }
    }
}

void SecDEL_ValToAdd(_DEL_ *_vDEL, DEL *aDEL)
{
    int i;

    DEL_init(aDEL);
    aDEL->current = _vDEL->current;
    aDEL->count = _vDEL->count;
    for (i = 0; i < _vDEL->count; i++)
    {
        aDEL->list[i].tag = _vDEL->list[i].tag;
        aDEL->list[i].length = _vDEL->list[i].length;
        //aDEL->list[i].ptValue = _vDEL->list[i].ptValue;
        memcpy(aDEL->list[i].ptValue, _vDEL->list[i].ptValue, aDEL
            ->list[i].length);
    }
}

void SecCopyEntree(DEL *aDEL, _DEL_ *_vDEL)
{
    int i;

    _DEL_init(_vDEL);
    if (aDEL != NULL)
    {
        _vDEL->current = aDEL->current;
        _vDEL->count = aDEL->count;
        if (aDEL->count < MAX_DATA_ELEMENT)
        {
            _vDEL->count = aDEL->count;
        }
        else
        {
            _vDEL->count = MAX_DATA_ELEMENT;
        }

        for (i = 0; i < _vDEL->count; i++)
        {
            _vDEL->list[i].tag = aDEL->list[i].tag;
            if (aDEL->list[i].length < MAX_ELT_LENGTH)
            {
                _vDEL->list[i].length = aDEL->list[i].length;
                memcpy(_vDEL->list[i].ptValue, &(aDEL->ValBuf[i][0]), aDEL
                    ->list[i].length);
            }
            else
            {
                _vDEL->list[i].length = MAX_ELT_LENGTH;
                memcpy(_vDEL->list[i].ptValue, &(aDEL->ValBuf[i][0]),
                    MAX_ELT_LENGTH);
            }
        }
    }
}

void SecCopySortie(_DEL_ *_vDEL, DEL *aDEL)
{
    int i;

    DEL_init(aDEL);
    aDEL->current = _vDEL->current;
    aDEL->count = _vDEL->count;
    for (i = 0; i < _vDEL->count; i++)
    {
        aDEL->list[i].tag = _vDEL->list[i].tag;
        //aDEL->list[i].ptValue = _vDEL->list[i].ptValue;
        if (_vDEL->list[i].length < MAX_ELT_LENGTH)
        {
            aDEL->list[i].length = _vDEL->list[i].length;
            memcpy(&(aDEL->ValBuf[i][0]), _vDEL->list[i].ptValue, aDEL
                ->list[i].length);
        }
        else
        {
            aDEL->list[i].length = MAX_ELT_LENGTH;
            memcpy(&(aDEL->ValBuf[i][0]), _vDEL->list[i].ptValue,
                MAX_ELT_LENGTH);
        }

    }
}

/*& BEGIN SMO/ETU/05/20028/MA  */
void SecDEL_CleanTags(DEL *aDEL)
{
    int i;
    int j;

    i = 0;
    j = 0;
    while (j < aDEL->count)
    {
        /*&BEGIN  FT/531/MA   Management of SECDEL functions                  */
        if ((aDEL->list[j].length == 0) || (aDEL->list[j].ptValue == NULL))
        /*&END  FT/531/MA   Management of SECDEL functions                  */
        {
            j++;
        }
        else
        {
            if (i != j)
            {
                aDEL->list[i].tag = aDEL->list[j].tag;
                aDEL->list[i].length = aDEL->list[j].length;
                /*&BEGIN  FT/531/MA   Management of SECDEL functions                  */
                //				aDEL->list[i].ptValue = &(aDEL->ValBuf[i][0]);
                /*&END  FT/531/MA   Management of SECDEL functions                  */

                memcpy(&(aDEL->ValBuf[i][0]), aDEL->list[j].ptValue, aDEL
                    ->list[j].length);
            }

            i++;
            j++;
        }
    }

    aDEL->current = 0;
    aDEL->count = i;
}

/*& END SMO/ETU/05/20028/MA */

/*&BEGIN  FT/531/MA   Management of SECDEL functions                  */
void SecDEL_FlushTags(DEL *aDEL)
{
    int i;
    int j;

    i = 0;
    j = 0;
    while (j < aDEL->count)
    {
        if (aDEL->list[j].tag == 0xFFFF)
        {
            j++;
        }
        else
        {
            if (i != j)
            {
                aDEL->list[i].tag = aDEL->list[j].tag;
                aDEL->list[i].length = aDEL->list[j].length;
                //				aDEL->list[i].ptValue = &(aDEL->ValBuf[i][0]);

                memcpy(&(aDEL->ValBuf[i][0]), aDEL->list[j].ptValue, aDEL
                    ->list[j].length);
            }

            i++;
            j++;
        }
    }

    aDEL->current = 0;
    aDEL->count = i;
}

/*&END  FT/531/MA   Management of SECDEL functions                  */
#endif

//-------------------------------------------------------------------------
void _DEL_init(_DEL_ *aDEL)
{
    int i;

    aDEL->current = 0;
    aDEL->count = 0;
    for (i = 0; i < MAX_DATA_ELEMENT; i++)
    {
        aDEL->list[i].tag = 0;
        aDEL->list[i].length = 0;
        memclr(aDEL->list[i].ptValue, sizeof(aDEL->list[i].ptValue));
    }
}

int _DEL_AddDataElement(_DEL_ *aDEL, const DataElement *AnElement)
{
    if (aDEL->count < MAX_DATA_ELEMENT)
    {
        aDEL->list[aDEL->count].tag = AnElement->tag;
        aDEL->list[aDEL->count].length = AnElement->length;
        if (AnElement->ptValue != NULL)
        {
            memcpy(aDEL->list[aDEL->count].ptValue, AnElement->ptValue,
                AnElement->length);
        }
        aDEL->count++;
        return 0;
    }
    else
        return  - 1;
}


_DataElement_ *_DEL_GetDataElement(_DEL_ *aDEL, int index)
{
    if ((aDEL != NULL) && (index > 0) && (index <= aDEL->count))
    {
        return (_DataElement_*)(&(aDEL->list[index - 1]));
    }
    else
    {
        return NULL;
    }

}

int _DEL_GetCount(_DEL_ *aDEL)
{
    if (aDEL != NULL)
    {
        return aDEL->count;
    }
    else
        return  - 1;

}


#ifndef _SECDEL_
void DEL_AddToVal(DEL *aDEL, _DEL_ *_vDEL)
{
    int i;

    _DEL_init(_vDEL);
    if (aDEL != NULL)
    {
        _vDEL->current = aDEL->current;
        _vDEL->count = aDEL->count;
        for (i = 0; i < aDEL->count; i++)
        {
            _vDEL->list[i].tag = aDEL->list[i].tag;
            _vDEL->list[i].length = aDEL->list[i].length;
            if (aDEL->list[i].ptValue != NULL)
            {
                memcpy(_vDEL->list[i].ptValue, aDEL->list[i].ptValue, aDEL
                    ->list[i].length);
            }
        }
    }
}

/*& BEGIN SMO/ETU/04/20167/LB : Portage vers SDK 30                        */
/*void DEL_ValToAdd(_DEL_ *_vDEL, DEL *aDEL)
{
int i;

DEL_init(aDEL);
aDEL->current = _vDEL->current;
aDEL->count   = _vDEL->count;
for (i=0; i<_vDEL->count; i++)
{
aDEL->list[i].tag     = _vDEL->list[i].tag;
aDEL->list[i].length  = _vDEL->list[i].length;
aDEL->list[i].ptValue = _vDEL->list[i].ptValue;
}
}
 */
/*& END SMO/ETU/04/20167/LB : Portage vers SDK 30                          */

void CopyEntree(DEL *aDEL, _DEL_ *_vDEL)
{
    int i;

    _DEL_init(_vDEL);
    if (aDEL != NULL)
    {
        _vDEL->current = aDEL->current;
        _vDEL->count = aDEL->count;
        for (i = 0; i < aDEL->count; i++)
        {
            _vDEL->list[i].tag = aDEL->list[i].tag;
            _vDEL->list[i].length = aDEL->list[i].length;
            if (aDEL->list[i].ptValue != NULL)
            {
                memcpy(_vDEL->list[i].ptValue, aDEL->list[i].ptValue, aDEL
                    ->list[i].length);
            }
        }
    }
}

void CopySortie(_DEL_ *_vDEL, DEL *aDEL)
{
    int i;

    DEL_init(aDEL);
    aDEL->current = _vDEL->current;
    aDEL->count = _vDEL->count;
    for (i = 0; i < _vDEL->count; i++)
    {
        aDEL->list[i].tag = _vDEL->list[i].tag;
        aDEL->list[i].length = _vDEL->list[i].length;
        aDEL->list[i].ptValue = _vDEL->list[i].ptValue;
    }
}

/*& BEGIN SMO/ETU/05/20028/MA  */
void DEL_CleanTags(DEL *aDEL)
{
    int i;
    int j;

    i = 0;
    j = 0;
    while (j < aDEL->count)
    {
        if ((aDEL->list[i].length == 0) || (aDEL->list[i].ptValue == NULL))
        {
            j++;
        }
        else
        {
            if (i != j)
            {
                aDEL->list[i].tag = aDEL->list[j].tag;
                aDEL->list[i].length = aDEL->list[j].length;
                aDEL->list[i].ptValue = aDEL->list[j].ptValue;
            }

            i++;
            j++;
        }
    }

    aDEL->current = 0;
    aDEL->count = i;
}

/*& END SMO/ETU/05/20028/MA */

void DEL_FlushTags(DEL *aDEL)
{

    int i;
    int j;

    i = 0;
    j = 0;
    while (j < aDEL->count)
    {
        if (aDEL->list[j].tag == 0xFFFF)
        {
            j++;
        }
        else
        {
            if (i != j)
            {
                aDEL->list[i].tag = aDEL->list[j].tag;
                aDEL->list[i].length = aDEL->list[j].length;
                aDEL->list[i].ptValue = aDEL->list[j].ptValue;
            }

            i++;
            j++;
        }
    }

    aDEL->current = 0;
    aDEL->count = i;
}

#endif

#endif

DEL *EMVDC_initiate_transaction(const DEL *aDEL)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_INITIATE_TRANSACTION, &priority) == 0)
    {
        if (aDEL != NULL)
            CopyEntree((DEL*)aDEL, &_DELLocale.DEL);
        else
            _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_INITIATE_TRANSACTION;
        USR_ServiceCall(96, SERVICE_EMVDC_INITIATE_TRANSACTION, sizeof
            (_DELLocale), &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        /* Call Track IAC facility of EMV TOOL                             */
        TrackIAC(aDEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}


DEL *EMVDC_process_transaction(const DEL *aDEL)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_PROCESS_TRANSACTION, &priority) == 0)
    {
        if (aDEL != NULL)
            CopyEntree((DEL*)aDEL, &_DELLocale.DEL);
        else
            _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_PROCESS_TRANSACTION;
        USR_ServiceCall(96, SERVICE_EMVDC_PROCESS_TRANSACTION, sizeof
            (_DELLocale), &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        /* Call Track IAC facility of EMV TOOL                             */
        TrackIAC(aDEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}

DEL *EMVDC_complete_transaction(const DEL *aDEL)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_COMPLETE_TRANSACTION, &priority) == 0)
    {
        if (aDEL != NULL)
            CopyEntree((DEL*)aDEL, &_DELLocale.DEL);
        else
            _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_COMPLETE_TRANSACTION;
        USR_ServiceCall(96, SERVICE_EMVDC_COMPLETE_TRANSACTION, sizeof
            (_DELLocale), &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        /* Call Track IAC facility of EMV TOOL                             */
        TrackIAC(aDEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}


DEL *EMVDC_get_data_elements(const DEL *aDEL)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_GET_DATA_ELEMENTS, &priority) == 0)
    {
        if (aDEL != NULL)
            CopyEntree((DEL*)aDEL, &_DELLocale.DEL);
        else
            _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_GET_DATA_ELEMENTS;
        USR_ServiceCall(96, SERVICE_EMVDC_GET_DATA_ELEMENTS, sizeof(_DELLocale),
            &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        /* Call Track IAC facility of EMV TOOL                             */
        TrackIAC(aDEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}


DEL *EMVDC_set_default_data_elements(const DEL *aDEL)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_SET_DEFAULT_DATA_ELEMENTS, &priority) == 0)
    {
        if (aDEL != NULL)
            CopyEntree((DEL*)aDEL, &_DELLocale.DEL);
        else
            _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_SET_DEFAULT_DATA_ELEMENTS;
        USR_ServiceCall(96, SERVICE_EMVDC_SET_DEFAULT_DATA_ELEMENTS, sizeof
            (_DELLocale), &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        /* Call Track IAC facility of EMV TOOL                             */
        TrackIAC(aDEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}


int EMVDC_dump_data_elements(void)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_DUMP_DATA_ELEMENTS, &priority) == 0)
    {
        _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_DUMP_DATA_ELEMENTS;
        USR_ServiceCall(96, SERVICE_EMVDC_DUMP_DATA_ELEMENTS, sizeof(_DELLocale)
            , &_DELLocale, &ret_code);
        return (_OK_);
    }
    else
        return (_KO_);
}

DEL *EMVDC_clear_default_data_elements(void)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_CLEAR_DEFAULT_DATA_ELEMENTS, &priority) ==
        0)
    {
        _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_CLEAR_DEFAULT_DATA_ELEMENTS;
        USR_ServiceCall(96, SERVICE_EMVDC_CLEAR_DEFAULT_DATA_ELEMENTS, sizeof
            (_DELLocale), &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}


DEL *EMVDC_get_default_data_elements(const DEL *aDEL)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_GET_DEFAULT_DATA_ELEMENTS, &priority) == 0)
    {
        if (aDEL != NULL)
            CopyEntree((DEL*)aDEL, &_DELLocale.DEL);
        else
            _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_GET_DEFAULT_DATA_ELEMENTS;
        USR_ServiceCall(96, SERVICE_EMVDC_GET_DEFAULT_DATA_ELEMENTS, sizeof
            (_DELLocale), &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        /* Call Track IAC facility of EMV TOOL                             */
        TrackIAC(aDEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}

DEL *EMVDC_application_selection(const DEL *aDEL)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_APPLICATION_SELECTION, &priority) == 0)
    {
        if (aDEL != NULL)
            CopyEntree((DEL*)aDEL, &_DELLocale.DEL);
        else
            _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_APPLICATION_SELECTION;
        USR_ServiceCall(96, SERVICE_EMVDC_APPLICATION_SELECTION, sizeof
            (_DELLocale), &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        /* Call Track IAC facility of EMV TOOL                             */
        TrackIAC(aDEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}

DEL *EMVDC_process_step(int function, const DEL *aDEL)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_PROCESS_STEP, &priority) == 0)
    {
        if (aDEL != NULL)
            CopyEntree((DEL*)aDEL, &_DELLocale.DEL);
        else
            _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_PROCESS_STEP;
        _DELLocale.function = function;
        USR_ServiceCall(96, SERVICE_EMVDC_PROCESS_STEP, sizeof(_DELLocale),
            &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        /* Call Track IAC facility of EMV TOOL                             */
        TrackIAC(aDEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}

/*& END SMO/ETU/03/2075/LB                                                 */

/* BEGIN TEDT/Z3/02/1314/PBE */
DEL *EMVDC_Get_Challenge(const DEL *aDEL)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_GET_CHALLENGE, &priority) == 0)
    {
        if (aDEL != NULL)
            CopyEntree((DEL*)aDEL, &_DELLocale.DEL);
        else
            _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_GET_CHALLENGE;
        USR_ServiceCall(96, SERVICE_EMVDC_GET_CHALLENGE, sizeof(_DELLocale),
            &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        /* Call Track IAC facility of EMV TOOL                             */
        TrackIAC(aDEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}

/* END TEDT/Z3/02/1314/PBE */


/*& BEGIN SMO/ETU/04/20017/LB                                              */
DEL *EMVDC_set_data_elements(const DEL *aDEL)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_SET_DATA_ELEMENTS, &priority) == 0)
    {
        if (aDEL != NULL)
            CopyEntree((DEL*)aDEL, &_DELLocale.DEL);
        else
            _DEL_init(&_DELLocale.DEL);
        _DELLocale.type_code = 96;
        _DELLocale.service = SERVICE_EMVDC_SET_DATA_ELEMENTS;
        USR_ServiceCall(96, SERVICE_EMVDC_SET_DATA_ELEMENTS, sizeof(_DELLocale),
            &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        /* Call Track IAC facility of EMV TOOL                             */
        TrackIAC(aDEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);
}

/*& END  SMO/ETU/04/20017/LB                                               */

/* &BEGIN SMO/ETU/04/20160/ma */
DEL *EMVDC_get_commands(int cmd_number)
{
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(96, SERVICE_EMVDC_GET_COMMAND, &priority) == 0)
    {
        _DELLocale.DEL.count = 0;
        _DELLocale.type_code = 96;
        _DELLocale.function = cmd_number;
        _DELLocale.service = SERVICE_EMVDC_GET_COMMAND;
        USR_ServiceCall(96, SERVICE_EMVDC_GET_COMMAND, sizeof(_DELLocale),
            &_DELLocale, &ret_code);
        CopySortie(&_DELLocale.DEL, &DELLocale);
        return (&DELLocale);
    }
    else
        return (NULL);

}

/* &END SMO/ETU/04/20160/ma */

/** Track trace
@param EntryDel entry data element list
@param OutputDel output data element list */
static void TrackIAC(const DEL *EntryDel, DEL *OutputDel)
{
    #ifdef _TRACK_IAC_DC_
    unsigned char priority;
    unsigned int ret_code;

    if (ServiceGet(I_EMVTOOL_Type_Appli, SERVICE_IAC_ENTRY, &priority) == 0)
    {
        CopyEntree((DEL*)EntryDel, &_DELSpy.DEL);
        _DELSpy.type_code = I_EMVDC_Type_Appli;
        _DELSpy.service = _DELLocale.service;
        _DELSpy.function = _DELLocale.function;
        USR_ServiceCall(I_EMVTOOL_Type_Appli, SERVICE_IAC_ENTRY, sizeof(_DELSpy)
            , &_DELSpy, &ret_code);
        CopyEntree(OutputDel, &_DELSpy.DEL);
        USR_ServiceCall(I_EMVTOOL_Type_Appli, SERVICE_IAC_OUTPUT, sizeof
            (_DELSpy), &_DELSpy, &ret_code);
    }
    #endif
}
